package cn.xetsoft.supermarket.util;

import cn.xetsoft.supermarket.common.DataResponse;
import cn.xetsoft.supermarket.dao.DbDao;
import cn.xetsoft.supermarket.dao.impl.DbDaoImpl;
import com.mysql.jdbc.CommunicationsException;

import java.sql.*;

/**
 * @author 侯国强
 * @since 2020/12/8 16:49
 * @version 1.0
 * @Description jdbc数据库连接工具
 */
public class JDBCUtils {

    //数据库配置类
    private static DbConfig dbConfig;
    //数据库连接保存
    private static Connection connection;
    //记录错误信息
    private static DataResponse response;

    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //创建配置类
        dbConfig = new DbConfig();
        /**
         * 初始化配置信息
         */
        //ip地址
        String address = PropertiesUtil.getProperty("db.host");
        dbConfig.setAddress(address);
        //设置端口
        int port = Integer.valueOf(PropertiesUtil.getProperty("db.port"));
        dbConfig.setPort(port);
        //设置数据库
        String database = PropertiesUtil.getProperty("db.dbname");
        dbConfig.setDatabase(database);
        //设置用户名
        String username = PropertiesUtil.getProperty("db.username");
        dbConfig.setUsername(username);
        //设置密码
        String password = PropertiesUtil.getProperty("db.password");
        dbConfig.setPassword(password);
        dbConfig.init();
    }

    //默认本地3306，用户root 密码root
    public static void init(String newDatabase){
        dbConfig.setDatabase(newDatabase);
        //刷新配置
        dbConfig.init();
    }

    //使用DbConfig dbConfig
    public static void init(DbConfig dbConfig){
        JDBCUtils.dbConfig = dbConfig;
        //刷新配置
        JDBCUtils.dbConfig.init();
    }

    //默认本地3306
    public static void init(String newDatabase,String newUser,String newPassword) {
        dbConfig.setDatabase(newDatabase);
        dbConfig.setUsername(newUser);
        dbConfig.setPassword(newPassword);
        //刷新配置
        dbConfig.init();
    }

    //全部参数 初始化
    public static void init(String newAddress,Integer newPort,String newDatabase,String newUser,String newPassword) {
        dbConfig.setAddress(newAddress);
        dbConfig.setPort(newPort);
        dbConfig.setDatabase(newDatabase);
        dbConfig.setUsername(newUser);
        dbConfig.setPassword(newPassword);
        //刷新配置
        dbConfig.init();
    }

    /**
     * 得到数据库的连接
     * 使用单例模式-懒汉模式 减少重复链接
     */
    public static Connection getInstanceConnection() {
        //懒汉模式
        if (connection != null){
            return connection;
        }
        try {
            connection = DriverManager.getConnection(dbConfig.getUrl(), dbConfig.getUsername(), dbConfig.getPassword());
            //如果数据库存在选择
            DbDao dbDao = new DbDaoImpl();
            if (dbDao.existDatabase(dbConfig.getDatabase())) {
                dbDao.useDatabase(dbConfig.getDatabase());
            }
        } catch (CommunicationsException exception){ //捕获连接异常
            System.out.println(exception.getMessage());
            response = DataResponse.error("数据库连接或者端口错误");
        } catch (SQLException throwables) { //捕获数据语法异常
            System.out.println(throwables.getMessage());
            String msg = throwables.getMessage();
            if (throwables.getMessage().contains("Unknown database")){ //判断数据库是否存在
                response = DataResponse.error(4041,"数据库不存在");
            } else if (msg.contains("using password: YES")){ //用户密码错误异常
                response = DataResponse.error("数据库 用户名或密码错误");
            }else { //通用处理
                response = DataResponse.errorException("连接错误");
            }
        }
        //返回数据
        return connection;
    }

    /**
     * 关闭连接
     */
    public static void close() {
        if (connection != null) {
            try {
                connection.close();
                connection = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static DbConfig getDbConfig() {
        return dbConfig;
    }

    public static void setDbConfig(DbConfig dbConfig) {
        JDBCUtils.dbConfig = dbConfig;
    }

    public static void setConnection(Connection connection) {
        JDBCUtils.connection = connection;
    }

    public static DataResponse getResponse() {
        return response;
    }

    public static void setResponse(DataResponse response) {
        JDBCUtils.response = response;
    }
}
